import * as fs from "fs";
import { Logger } from "@nestjs/common";
import { useWebxueConfig } from "../../webxue.config";
import { PackageJson } from "tsconfig-paths/lib/filesystem";
import * as process from "process";

export class PackageScript {
  // 分隔符
  static separator = "--------------------";

  // 初始化package.json["scripts"]
  static async initScript() {
    const webxueConfig = useWebxueConfig();

    const packageJson = (await PackageScript.getPackageJson()) as PackageJson;

    // 启动脚本
    for(const envKey in webxueConfig.env) {
      if(webxueConfig.env[envKey].mode === "dev") {
        packageJson.scripts["开发环境启动"] = PackageScript.separator;
        packageJson.scripts[`start:${envKey}`] = `npm run set:${envKey} && nest start --watch`;
      } else if(webxueConfig.env[envKey].mode === "prod") {
        packageJson.scripts["生产环境启动"] = PackageScript.separator;
        packageJson.scripts[`start:${envKey}`] = `npm run build:${envKey} && npm run pm2:start`;
      }
    }

    // 打包脚本
    for(const envKey in webxueConfig.env) {
      if(webxueConfig.env[envKey].mode === "prod") {
        packageJson.scripts["生产环境打包"] = PackageScript.separator;
        packageJson.scripts[`build:${envKey}`] = `rimraf dist && nest build && npm run set:${envKey}`;
      }
    }

    // 追加环境变量脚本
    packageJson.scripts["设置环境变量"] = PackageScript.separator;
    for(const envKey in webxueConfig.env) {
      packageJson.scripts[`set:${envKey}`] = `ts-node src/scripts/npm.script env=${envKey}`
    }

    // 开启pm2脚本
    packageJson.scripts["pm2启动"] = PackageScript.separator;
    packageJson.scripts["pm2:start"] = `pm2 start dist/main.js --name ${packageJson.name}`;

    // 设置脚本命令
    await PackageScript.setPackageJson(packageJson,"成功初始化 package.json 文件")
  }

  // 重置package.json["scripts"]
  static async resetScript(){
    const scripts = {
      "prebuild": "rimraf dist",
      "build": "nest build && ts-node src/utils/scripts/npm.script env=production",
      "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
      "start": "nest start",
      "start:dev": "ts-node src/utils/scripts/npm.script env=development && nest start --watch",
      "start:debug": "nest start --debug --watch",
      "start:prod": "node dist/main",
      "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
      "test": "jest",
      "test:watch": "jest --watch",
      "test:cov": "jest --coverage",
      "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
      "test:e2e": "jest --config ./test/jest-e2e.json",
      "init:scripts": "ts-node src/scripts/package.script.ts init-scripts",
      "reset:scripts": "ts-node src/scripts/package.script.ts reset-scripts"
    }
    const packageJson = (await PackageScript.getPackageJson()) as PackageJson;
    packageJson.scripts = scripts;
    await PackageScript.setPackageJson(packageJson,"成功重置 package.json 文件");
  }

  // 读取package.json
  static getPackageJson(){
    return new Promise((resolve,reject) => {
      try {
        const data = fs.readFileSync("package.json", "utf8");
        resolve(JSON.parse(data));
      } catch (err) {
        Logger.error(err.message);
        reject(err);
      }
    })
  }

  // 写入package.json
  static async setPackageJson(packageJson:PackageJson, message:string){
    return new Promise<void>((resolve,reject) => {
      try {
        // 将修改后的内容写回 package.json 文件
        fs.writeFileSync("package.json", JSON.stringify(packageJson, null, 2));
        Logger.log(message);
        resolve()
      }catch (err) {
        reject(err);
      }
    })
  }
}

// 参数类型 init-scripts(初始化脚本命令) reset-scripts(重置脚本命令)
export type Argument = "init-scripts" | "reset-scripts";

(async () => {
  // 获取参数
  const args = process.argv.slice(2) as Argument[];
  // 存在重置命令，先重置
  if(args.includes("reset-scripts")) await PackageScript.resetScript();
  // 存在初始化命令，初始化
  if(args.includes("init-scripts")) await PackageScript.initScript();
})()
